home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / taitosj.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  23KB  |  888 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #ifndef MIN
  13. #define MIN(x,y) (x)<(y)?(x):(y)
  14. #endif
  15.  
  16.  
  17. unsigned char *taitosj_videoram2,*taitosj_videoram3;
  18. unsigned char *taitosj_characterram;
  19. unsigned char *taitosj_scroll;
  20. unsigned char *taitosj_colscrolly;
  21. unsigned char *taitosj_gfxpointer;
  22. unsigned char *taitosj_colorbank,*taitosj_video_priority;
  23. static unsigned char taitosj_collision_reg[4];
  24. static unsigned char *dirtybuffer2,*dirtybuffer3;
  25. static struct osd_bitmap *taitosj_tmpbitmap[3];
  26. static struct osd_bitmap *sprite_sprite_collbitmap1,*sprite_sprite_collbitmap2;
  27. static struct osd_bitmap *sprite_plane_collbitmap1;
  28. static struct osd_bitmap *sprite_plane_collbitmap2[3];
  29. static unsigned char dirtycharacter1[256],dirtycharacter2[256];
  30. static unsigned char dirtysprite1[64],dirtysprite2[64];
  31. static int taitosj_video_enable;
  32. static int flipscreen[2];
  33. static struct rectangle spritearea[32]; /*areas on bitmap (sprite locations)*/
  34. static int spriteon[32]; /* 1 if sprite is active */
  35.  
  36. static int playfield_enable_mask[3] = { 0x10, 0x20, 0x40 };
  37.  
  38.  
  39. /***************************************************************************
  40.  
  41.   I call the three planes with the conventional names "front", "middle" and
  42.   "back", because that's their default order, but they can be arranged,
  43.   together with the sprites, in any order. The priority is selected by
  44.   register 0xd300, which works as follow:
  45.  
  46.   bits 0-3 go to A4-A7 of a 256x4 PROM
  47.   bit 4 selects D0/D1 or D2/D3 of the PROM
  48.   bit 5-7 n.c.
  49.   A0-A3 of the PROM is fed with a mask of the inactive planes
  50.   (i.e. all-zero) in the order sprites-front-middle-back
  51.   the 2-bit code which comes out from the PROM selects the plane
  52.   to display.
  53.  
  54.   Here is a dump of one of these PROMs; on the right is the resulting order
  55.   (s = sprites f = front m = middle b = back). Note that, in theory, the
  56.   PROM could encode some really funky priority schemes which couldn't be
  57.   reconducted to the simple layer order given here. Luckily, none of the
  58.   games seem to do that. Actually, all of them seem to use the same PROM,
  59.   with the exception of Wild Western.
  60.  
  61.                                                         d300 pri    d300 pri
  62.   00: 08 09 08 0A 00 05 00 0F 08 09 08 0A 00 05 00 0F |  00  sfmb    10  msfb
  63.   10: 08 09 08 0B 00 0D 00 0F 08 09 08 0A 00 05 00 0F |  01  sfbm    11  msbf
  64.   20: 08 0A 08 0A 04 05 00 0F 08 0A 08 0A 04 05 00 0F |  02  smfb    12  mfsb
  65.   30: 08 0A 08 0A 04 07 0C 0F 08 0A 08 0A 04 05 00 0F |  03  smbf    13  mfbs
  66.   40: 08 0B 08 0B 0C 0F 0C 0F 08 09 08 0A 00 05 00 0F |  04  sbfm    14  mbsf
  67.   50: 08 0B 08 0B 0C 0F 0C 0F 08 0A 08 0A 04 05 00 0F |  05  sbmf    15  mbfs
  68.   60: 0D 0D 0C 0E 0D 0D 0C 0F 01 05 00 0A 01 05 00 0F |  06  fsmb    16  bsfm
  69.   70: 0D 0D 0C 0F 0D 0D 0C 0F 01 09 00 0A 01 05 00 0F |  07  fsbm    17  bsmf
  70.   80: 0D 0D 0E 0E 0D 0D 0C 0F 05 05 02 0A 05 05 00 0F |  08  fmsb    18  bfsm
  71.   90: 0D 0D 0E 0E 0D 0D 0F 0F 05 05 0A 0A 05 05 00 0F |  09  fmbs    19  bfms
  72.   A0: 0D 0D 0F 0F 0D 0D 0F 0F 09 09 08 0A 01 05 00 0F |  0A  fbsm    1A  bmsf
  73.   B0: 0D 0D 0F 0F 0D 0D 0F 0F 09 09 0A 0A 05 05 00 0F |  0B  fbms    1B  bmfs
  74.   C0: 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F |  0C   -      1C   -
  75.   D0: 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F |  0D   -      1D   -
  76.   E0: 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F |  0E   -      1E   -
  77.   F0: 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F |  0F   -      1F   -
  78.  
  79. ***************************************************************************/
  80.  
  81. static int draworder[32][4];
  82.  
  83.  
  84. /***************************************************************************
  85.  
  86.   Convert the color PROMs into a more useable format.
  87.  
  88.   The Taito games don't have a color PROM. They use RAM to dynamically
  89.   create the palette. The resolution is 9 bit (3 bits per gun).
  90.  
  91.   The RAM is connected to the RGB output this way:
  92.  
  93.   bit 0 -- inverter -- 220 ohm resistor  -- RED
  94.   bit 7 -- inverter -- 470 ohm resistor  -- RED
  95.         -- inverter -- 1  kohm resistor  -- RED
  96.         -- inverter -- 220 ohm resistor  -- GREEN
  97.         -- inverter -- 470 ohm resistor  -- GREEN
  98.         -- inverter -- 1  kohm resistor  -- GREEN
  99.         -- inverter -- 220 ohm resistor  -- BLUE
  100.         -- inverter -- 470 ohm resistor  -- BLUE
  101.   bit 0 -- inverter -- 1  kohm resistor  -- BLUE
  102.  
  103. ***************************************************************************/
  104.  
  105. void taitosj_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  106. {
  107.     int i;
  108.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  109.  
  110.     /* all gfx elements use the same palette */
  111.     for (i = 0;i < 64;i++)
  112.     {
  113.         COLOR(0,i) = i;
  114.         /* we create both a "normal" lookup table and one where pen 0 is */
  115.         /* always mapped to color 0. This is needed for transparency. */
  116.         if (i % 8 == 0) COLOR(0,i + 64) = 0;
  117.         else COLOR(0,i + 64) = i;
  118.     }
  119.  
  120.  
  121.     /* do a simple conversion of the PROM into layer priority order. Note that */
  122.     /* this is a simplification, which assumes the PROM encodes a sensible priority */
  123.     /* scheme. */
  124.     color_prom = memory_region(REGION_PROMS);
  125.     for (i = 0;i < 32;i++)
  126.     {
  127.         int j,mask;
  128.  
  129.         mask = 0;    /* start with all four layers active, so we'll get the highest */
  130.                     /* priority one in the first loop */
  131.  
  132.         for (j = 3;j >= 0;j--)
  133.         {
  134.             int data;
  135.  
  136.             data = color_prom[0x10 * (i & 0x0f) + mask];
  137.             if (i & 0x10) data >>= 2;
  138.             data &= 0x03;
  139.             mask |= (1 << data);    /* in next loop, we'll see which of the remaining */
  140.                                     /* layers has top priority when this one is transparent */
  141.             draworder[i][j] = data;
  142.         }
  143.     }
  144. }
  145.  
  146.  
  147.  
  148. WRITE_HANDLER( taitosj_paletteram_w )
  149. {
  150.     int bit0,bit1,bit2;
  151.     int r,g,b,val;
  152.  
  153.  
  154.     paletteram[offset] = data;
  155.  
  156.     /* red component */
  157.     val = paletteram[offset | 1];
  158.     bit0 = (~val >> 6) & 0x01;
  159.     bit1 = (~val >> 7) & 0x01;
  160.     val = paletteram[offset & ~1];
  161.     bit2 = (~val >> 0) & 0x01;
  162.     r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  163.  
  164.     /* green component */
  165.     val = paletteram[offset | 1];
  166.     bit0 = (~val >> 3) & 0x01;
  167.     bit1 = (~val >> 4) & 0x01;
  168.     bit2 = (~val >> 5) & 0x01;
  169.     g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  170.  
  171.     /* blue component */
  172.     val = paletteram[offset | 1];
  173.     bit0 = (~val >> 0) & 0x01;
  174.     bit1 = (~val >> 1) & 0x01;
  175.     bit2 = (~val >> 2) & 0x01;
  176.     b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
  177.  
  178.     palette_change_color(offset / 2,r,g,b);
  179. }
  180.  
  181.  
  182.  
  183. /***************************************************************************
  184.  
  185.   Start the video hardware emulation.
  186.  
  187. ***************************************************************************/
  188. int taitosj_vh_start(void)
  189. {
  190.     int i;
  191.  
  192.  
  193.     taitosj_tmpbitmap[0] = taitosj_tmpbitmap[1] = taitosj_tmpbitmap[2] = 0;
  194.     sprite_sprite_collbitmap2 = sprite_sprite_collbitmap1 = 0;
  195.     sprite_plane_collbitmap1 = 0;
  196.     sprite_plane_collbitmap2[0] = sprite_plane_collbitmap2[1] = sprite_plane_collbitmap2[2] = 0;
  197.     dirtybuffer3  = dirtybuffer2 = 0;
  198.  
  199.  
  200.     if (generic_vh_start() != 0)
  201.         return 1;
  202.  
  203.     if ((dirtybuffer2 = malloc(videoram_size)) == 0)
  204.     {
  205.         generic_vh_stop();
  206.         return 1;
  207.     }
  208.     memset(dirtybuffer2,1,videoram_size);
  209.  
  210.     if ((dirtybuffer3 = malloc(videoram_size)) == 0)
  211.     {
  212.         generic_vh_stop();
  213.         return 1;
  214.     }
  215.     memset(dirtybuffer3,1,videoram_size);
  216.  
  217.     if ((sprite_plane_collbitmap1 = osd_create_bitmap(16,16)) == 0)
  218.     {
  219.         generic_vh_stop();
  220.         return 1;
  221.     }
  222.  
  223.     for (i = 0; i < 3; i++)
  224.     {
  225.         if ((taitosj_tmpbitmap[i] = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  226.         {
  227.             generic_vh_stop();
  228.             return 1;
  229.         }
  230.  
  231.         if ((sprite_plane_collbitmap2[i] = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  232.         {
  233.             generic_vh_stop();
  234.             return 1;
  235.         }
  236.  
  237.     }
  238.  
  239.     if ((sprite_sprite_collbitmap1 = osd_create_bitmap(32,32)) == 0)
  240.     {
  241.         generic_vh_stop();
  242.         return 1;
  243.     }
  244.  
  245.     if ((sprite_sprite_collbitmap2 = osd_create_bitmap(32,32)) == 0)
  246.     {
  247.         generic_vh_stop();
  248.         return 1;
  249.     }
  250.  
  251.     flipscreen[0] = flipscreen[1] = 0;
  252.  
  253.     return 0;
  254. }
  255.  
  256.  
  257.  
  258. /***************************************************************************
  259.  
  260.   Stop the video hardware emulation.
  261.  
  262. ***************************************************************************/
  263. void taitosj_vh_stop(void)
  264. {
  265.     int i;
  266.  
  267.  
  268.     if (sprite_sprite_collbitmap2) osd_free_bitmap(sprite_sprite_collbitmap2);
  269.     if (sprite_sprite_collbitmap1) osd_free_bitmap(sprite_sprite_collbitmap1);
  270.     if (sprite_plane_collbitmap1) osd_free_bitmap(sprite_plane_collbitmap1);
  271.  
  272.     for (i = 0; i < 3; i++)
  273.     {
  274.         if (taitosj_tmpbitmap[i]) osd_free_bitmap(taitosj_tmpbitmap[i]);
  275.         if (sprite_plane_collbitmap2[i]) osd_free_bitmap(sprite_plane_collbitmap2[i]);
  276.     }
  277.  
  278.     if (dirtybuffer3) free(dirtybuffer3);
  279.     if (dirtybuffer2) free(dirtybuffer2);
  280.     generic_vh_stop();
  281. }
  282.  
  283.  
  284.  
  285. READ_HANDLER( taitosj_gfxrom_r )
  286. {
  287.     int offs;
  288.  
  289.  
  290.     offs = taitosj_gfxpointer[0]+taitosj_gfxpointer[1]*256;
  291.  
  292.     taitosj_gfxpointer[0]++;
  293.     if (taitosj_gfxpointer[0] == 0) taitosj_gfxpointer[1]++;
  294.  
  295.     if (offs < 0x8000)
  296.         return memory_region(REGION_GFX1)[offs];
  297.     else return 0;
  298. }
  299.  
  300.  
  301.  
  302. WRITE_HANDLER( taitosj_videoram2_w )
  303. {
  304.     if (taitosj_videoram2[offset] != data)
  305.     {
  306.         dirtybuffer2[offset] = 1;
  307.  
  308.         taitosj_videoram2[offset] = data;
  309.     }
  310. }
  311.  
  312.  
  313.  
  314. WRITE_HANDLER( taitosj_videoram3_w )
  315. {
  316.     if (taitosj_videoram3[offset] != data)
  317.     {
  318.         dirtybuffer3[offset] = 1;
  319.  
  320.         taitosj_videoram3[offset] = data;
  321.     }
  322. }
  323.  
  324.  
  325.  
  326. WRITE_HANDLER( taitosj_colorbank_w )
  327. {
  328.     if (taitosj_colorbank[offset] != data)
  329.     {
  330. logerror("colorbank %d = %02x\n",offset,data);
  331.         memset(dirtybuffer,1,videoram_size);
  332.         memset(dirtybuffer2,1,videoram_size);
  333.         memset(dirtybuffer3,1,videoram_size);
  334.  
  335.         taitosj_colorbank[offset] = data;
  336.     }
  337. }
  338.  
  339.  
  340.  
  341. WRITE_HANDLER( taitosj_videoenable_w )
  342. {
  343.     if (taitosj_video_enable != data)
  344.     {
  345. logerror("videoenable = %02x\n",data);
  346.  
  347.         if ((taitosj_video_enable & 3) != (data & 3))
  348.         {
  349.             flipscreen[0] = data & 1;
  350.             flipscreen[1] = data & 2;
  351.  
  352.             memset(dirtybuffer,1,videoram_size);
  353.             memset(dirtybuffer2,1,videoram_size);
  354.             memset(dirtybuffer3,1,videoram_size);
  355.         }
  356.  
  357.         taitosj_video_enable = data;
  358.     }
  359. }
  360.  
  361.  
  362.  
  363. WRITE_HANDLER( taitosj_characterram_w )
  364. {
  365.     if (taitosj_characterram[offset] != data)
  366.     {
  367.         if (offset < 0x1800)
  368.         {
  369.             dirtycharacter1[(offset / 8) & 0xff] = 1;
  370.             dirtysprite1[(offset / 32) & 0x3f] = 1;
  371.         }
  372.         else
  373.         {
  374.             dirtycharacter2[(offset / 8) & 0xff] = 1;
  375.             dirtysprite2[(offset / 32) & 0x3f] = 1;
  376.         }
  377.  
  378.         taitosj_characterram[offset] = data;
  379.     }
  380. }
  381.  
  382.  
  383. /***************************************************************************
  384.  
  385.   As if the hardware weren't complicated enough, it also has built-in
  386.   collision detection.
  387.  
  388. ***************************************************************************/
  389. READ_HANDLER( taitosj_collision_reg_r )
  390. {
  391.     return taitosj_collision_reg[offset];
  392. }
  393.  
  394. WRITE_HANDLER( taitosj_collision_reg_clear_w )
  395. {
  396.     taitosj_collision_reg[0] = 0;
  397.     taitosj_collision_reg[1] = 0;
  398.     taitosj_collision_reg[2] = 0;
  399.     taitosj_collision_reg[3] = 0;
  400. }
  401.  
  402. INLINE int get_sprite_xy(UINT8 num, UINT8* sx, UINT8* sy)
  403. {
  404.     int offs = num * 4;
  405.  
  406.  
  407.     *sx = spriteram[offs] - 1;
  408.     *sy = 240 - spriteram[offs + 1];
  409.     return (*sy < 240);
  410. }
  411.  
  412.  
  413. static int check_sprite_sprite_bitpattern(int sx1, int sy1, int num1,
  414.                                           int sx2, int sy2, int num2)
  415. {
  416.     int x,y,minx,miny,maxx = 16,maxy = 16;
  417.     int offs1 = num1 * 4;
  418.     int offs2 = num2 * 4;
  419.  
  420.     /* normalize coordinates to (0,0) and compute overlap */
  421.     if (sx1 < sx2)
  422.     {
  423.         sx2 -= sx1;
  424.         sx1 = 0;
  425.         minx = sx2;
  426.     }
  427.     else
  428.     {
  429.         sx1 -= sx2;
  430.         sx2 = 0;
  431.         minx = sx1;
  432.     }
  433.  
  434.     if (sy1 < sy2)
  435.     {
  436.         sy2 -= sy1;
  437.         sy1 = 0;
  438.         miny = sy2;
  439.     }
  440.     else
  441.     {
  442.         sy1 -= sy2;
  443.         sy2 = 0;
  444.         miny = sy1;
  445.     }
  446.  
  447.     /* draw the sprites into seperate bitmaps and check overlapping region */
  448.     drawgfx(sprite_sprite_collbitmap1,Machine->gfx[(spriteram[offs1 + 3] & 0x40) ? 3 : 1],
  449.             spriteram[offs1 + 3] & 0x3f,
  450.             0,
  451.             spriteram[offs1 + 2] & 1, spriteram[offs1 + 2] & 2,
  452.             sx1,sy1,
  453.             0,TRANSPARENCY_NONE,0);
  454.  
  455.     drawgfx(sprite_sprite_collbitmap2,Machine->gfx[(spriteram[offs2 + 3] & 0x40) ? 3 : 1],
  456.             spriteram[offs2 + 3] & 0x3f,
  457.             0,
  458.             spriteram[offs2 + 2] & 1, spriteram[offs2 + 2] & 2,
  459.             sx2,sy2,
  460.             0,TRANSPARENCY_NONE,0);
  461.  
  462.     for (y = miny;y < maxy;y++)
  463.     {
  464.         for(x = minx;x < maxx;x++)
  465.         {
  466.             if ((read_pixel(sprite_sprite_collbitmap1, x, y) != Machine->pens[0]) &&
  467.                 (read_pixel(sprite_sprite_collbitmap2, x, y) != Machine->pens[0]))
  468.             {
  469.                 return 1;  /* collided */
  470.             }
  471.         }
  472.     }
  473.  
  474.     return 0;
  475. }
  476.  
  477.  
  478. static void check_sprite_sprite_collision(void)
  479. {
  480.     UINT8 i,j,sx1,sx2,sy1,sy2;
  481.  
  482.  
  483.     /* chech each pair of sprites */
  484.     for (i = 0x00; i < 0x20; i++)
  485.     {
  486.         if ((i >= 0x10) && (i <= 0x17)) continue;    /* no sprites here */
  487.  
  488.         if (get_sprite_xy(i, &sx1, &sy1))
  489.         {
  490.             for (j = 0x00; j < 0x20; j++)
  491.             {
  492.                 if (j >= i)     break;        /* only check a pair once and don't check against itself */
  493.  
  494.                 if ((j >= 0x10) && (j <= 0x17)) continue;      /* no sprites here */
  495.  
  496.                 if (get_sprite_xy(j, &sx2, &sy2))
  497.                 {
  498.                     /* rule out any pairs that cannot be touching */
  499.                     if ((abs((INT8)sx1 - (INT8)sx2) < 16) &&
  500.                         (abs((INT8)sy1 - (INT8)sy2) < 16))
  501.                     {
  502.                         if (check_sprite_sprite_bitpattern(sx1, sy1, i, sx2, sy2, j))
  503.                         {
  504.                             /* mark sprites as collided */
  505.                             int reg1,reg2;
  506.  
  507.                             reg1 = i >> 3;
  508.                             if (reg1 == 3)  reg1 = 2;
  509.  
  510.                             reg2 = j >> 3;
  511.                             if (reg2 == 3)  reg2 = 2;
  512.  
  513.                             taitosj_collision_reg[reg1] |= (1 << (i & 0x07));
  514.                             taitosj_collision_reg[reg2] |= (1 << (j & 0x07));
  515.                         }
  516.                     }
  517.                 }
  518.             }
  519.         }
  520.     }
  521. }
  522.  
  523.  
  524. static void calculate_sprites_areas(void)
  525. {
  526.     UINT8 sx,sy;
  527.     int i,minx,miny,maxx,maxy;
  528.  
  529.     for (i = 0x00; i < 0x20; i++)
  530.     {
  531.         if ((i >= 0x10) && (i <= 0x17)) continue;    /* no sprites here */
  532.  
  533.         if (get_sprite_xy(i, &sx, &sy))
  534.         {
  535.             minx = sx;
  536.             miny = sy;
  537.  
  538.             maxx = minx+15;
  539.             maxy = miny+15;
  540.  
  541.             /* check for bitmap bounds to avoid illegal memory access */
  542.             if (minx < 0) minx = 0;
  543.             if (miny < 0) miny = 0;
  544.             if (maxx >= Machine->drv->screen_width - 1)
  545.                 maxx = Machine->drv->screen_width - 1;
  546.             if (maxy >= Machine->drv->screen_height - 1)
  547.                 maxy = Machine->drv->screen_height - 1;
  548.  
  549.             spritearea[i].min_x = minx;
  550.             spritearea[i].max_x = maxx;
  551.             spritearea[i].min_y = miny;
  552.             spritearea[i].max_y = maxy;
  553.             spriteon[i] = 1;
  554.         }
  555.         else /* sprite is off */
  556.         {
  557.             spriteon[i] = 0;
  558.         }
  559.     }
  560. }
  561.  
  562. static int check_sprite_plane_bitpattern(int num)
  563. {
  564.     int x,y,flipx,flipy,minx,miny,maxx,maxy;
  565.     int offs = num * 4;
  566.     int result = 0;  /* no collisions */
  567.  
  568.     int    check_playfield1 = taitosj_video_enable & playfield_enable_mask[0];
  569.     int    check_playfield2 = taitosj_video_enable & playfield_enable_mask[1];
  570.     int    check_playfield3 = taitosj_video_enable & playfield_enable_mask[2];
  571.  
  572.     minx = spritearea[num].min_x;
  573.     miny = spritearea[num].min_y;
  574.     maxx = spritearea[num].max_x + 1;
  575.     maxy = spritearea[num].max_y + 1;
  576.  
  577.  
  578.     flipx = spriteram[offs + 2] & 1;
  579.     flipy = spriteram[offs + 2] & 2;
  580.  
  581.     if (flipscreen[0])
  582.     {
  583.         flipx = !flipx;
  584.         minx = MIN(minx + 2, Machine->drv->screen_width);
  585.         maxx = MIN(maxx + 2, Machine->drv->screen_width);
  586.     }
  587.     if (flipscreen[1])
  588.     {
  589.         flipy = !flipy;
  590.         miny = MIN(miny + 2, Machine->drv->screen_height);
  591.         maxy = MIN(maxy + 2, Machine->drv->screen_height);
  592.     }
  593.  
  594.     /* draw sprite into a bitmap and check if playfields collide */
  595.     drawgfx(sprite_plane_collbitmap1, Machine->gfx[(spriteram[offs + 3] & 0x40) ? 3 : 1],
  596.             spriteram[offs + 3] & 0x3f,
  597.             0,
  598.             flipx, flipy,
  599.             0,0,
  600.             0,TRANSPARENCY_NONE,0);
  601.  
  602.     for (y = miny;y < maxy;y++)
  603.     {
  604.         for (x = minx;x < maxx;x++)
  605.         {
  606.             if (read_pixel(sprite_plane_collbitmap1, x-minx, y-miny) != Machine->pens[0]) /* is there anything to check for ? */
  607.             {
  608.                 if (check_playfield1 && (read_pixel(sprite_plane_collbitmap2[0], x, y) != Machine->pens[0]))
  609.                 {
  610.                     result |= 1;  /* collided */
  611.                     if (result == 7)  goto done;
  612.                     check_playfield1 = 0;
  613.                 }
  614.                 if (check_playfield2 && (read_pixel(sprite_plane_collbitmap2[1], x, y) != Machine->pens[0]))
  615.                 {
  616.                     result |= 2;  /* collided */
  617.                     if (result == 7)  goto done;
  618.                     check_playfield2 = 0;
  619.  
  620.                 }
  621.                 if (check_playfield3 && (read_pixel(sprite_plane_collbitmap2[2], x, y) != Machine->pens[0]))
  622.                 {
  623.                     result |= 4;  /* collided */
  624.                     if (result == 7)  goto done;
  625.                     check_playfield3 = 0;
  626.                 }
  627.             }
  628.         }
  629.     }
  630.  
  631. done:
  632.     return result;
  633. }
  634.  
  635. static void check_sprite_plane_collision(void)
  636. {
  637.     UINT8 i;
  638.  
  639.  
  640.     /* check each sprite */
  641.     for (i = 0x00; i < 0x20; i++)
  642.     {
  643.         if ((i >= 0x10) && (i <= 0x17)) continue;    /* no sprites here */
  644.  
  645.         if (spriteon[i])
  646.         {
  647.             taitosj_collision_reg[3] |= check_sprite_plane_bitpattern(i);
  648.         }
  649.     }
  650. }
  651.  
  652.  
  653. static void drawsprites(struct osd_bitmap *bitmap)
  654. {
  655.     /* Draw the sprites. Note that it is important to draw them exactly in this */
  656.     /* order, to have the correct priorities (but they are still wrong sometimes.) */
  657.     if (taitosj_video_enable & 0x80)
  658.     {
  659.         int offs;
  660.  
  661.  
  662.         for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  663.         {
  664.             UINT8 sx,sy,flipx,flipy;
  665.  
  666.  
  667.             if ((offs >= 0x40) && (offs <= 0x5f))  continue;    /* no sprites here */
  668.  
  669.  
  670.             if (get_sprite_xy(offs / 4, &sx, &sy))
  671.             {
  672.                 flipx = spriteram[offs + 2] & 1;
  673.                 flipy = spriteram[offs + 2] & 2;
  674.                 if (flipscreen[0])
  675.                 {
  676.                     sx = 238 - sx;
  677.                     flipx = !flipx;
  678.                 }
  679.                 if (flipscreen[1])
  680.                 {
  681.                     sy = 242 - sy;
  682.                     flipy = !flipy;
  683.                 }
  684.  
  685.                 drawgfx(bitmap,Machine->gfx[(spriteram[offs + 3] & 0x40) ? 3 : 1],
  686.                         spriteram[offs + 3] & 0x3f,
  687.                         2 * ((taitosj_colorbank[1] >> 4) & 0x03) + ((spriteram[offs + 2] >> 2) & 1),
  688.                         flipx,flipy,
  689.                         sx,sy,
  690.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  691.  
  692.                 /* draw with wrap around. The horizontal games (eg. sfposeid) need this */
  693.                 drawgfx(bitmap,Machine->gfx[(spriteram[offs + 3] & 0x40) ? 3 : 1],
  694.                         spriteram[offs + 3] & 0x3f,
  695.                         2 * ((taitosj_colorbank[1] >> 4) & 0x03) + ((spriteram[offs + 2] >> 2) & 1),
  696.                         flipx,flipy,
  697.                         sx - 0x100,sy,
  698.                         &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  699.             }
  700.         }
  701.     }
  702. }
  703.  
  704.  
  705. static void drawplayfield(int n, struct osd_bitmap *bitmap)
  706. {
  707.     static int fudge1[3] = { 3,  1, -1 };
  708.     static int fudge2[3] = { 8, 10, 12 };
  709.  
  710.     if (taitosj_video_enable & playfield_enable_mask[n])
  711.     {
  712.         int i,scrollx,scrolly[32];
  713.  
  714.  
  715.         scrollx = taitosj_scroll[2*n];
  716.         if (flipscreen[0])
  717.             scrollx =  (scrollx & 0xf8) + ((scrollx + fudge1[n]) & 7) + fudge2[n];
  718.         else
  719.             scrollx = -(scrollx & 0xf8) + ((scrollx + fudge1[n]) & 7) + fudge2[n];
  720.  
  721.         if (flipscreen[1])
  722.         {
  723.             for (i = 0;i < 32;i++)
  724.                 scrolly[31-i] =  taitosj_colscrolly[32*n+i] + taitosj_scroll[2*n+1];
  725.         }
  726.         else
  727.         {
  728.             for (i = 0;i < 32;i++)
  729.                 scrolly[i]    = -taitosj_colscrolly[32*n+i] - taitosj_scroll[2*n+1];
  730.         }
  731.  
  732.         copyscrollbitmap(bitmap,taitosj_tmpbitmap[n],1,&scrollx,32,scrolly,&Machine->drv->visible_area,TRANSPARENCY_COLOR,0);
  733.  
  734.         /* store parts covered with sprites for sprites/playfields collision detection */
  735.         for (i=0x00; i<0x20; i++)
  736.         {
  737.             if ((i >= 0x10) && (i <= 0x17)) continue; /* no sprites here */
  738.             if (spriteon[i])
  739.                 copyscrollbitmap( sprite_plane_collbitmap2[n],taitosj_tmpbitmap[n],1,&scrollx,32,scrolly,&spritearea[i],TRANSPARENCY_NONE,0);
  740.         }
  741.     }
  742. }
  743.  
  744.  
  745. static void drawplane(int n,struct osd_bitmap *bitmap)
  746. {
  747.     switch (n)
  748.     {
  749.     case 0:
  750.         drawsprites(bitmap);
  751.         break;
  752.     case 1:
  753.     case 2:
  754.     case 3:
  755.         drawplayfield(n-1,bitmap);
  756.         break;
  757.     }
  758. }
  759.  
  760.  
  761. void taitosj_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  762. {
  763.     int offs,i;
  764.  
  765.  
  766.     /* update palette */
  767.     if (palette_recalc())
  768.     {
  769.         memset(dirtybuffer, 1, videoram_size);
  770.         memset(dirtybuffer2, 1, videoram_size);
  771.         memset(dirtybuffer3, 1, videoram_size);
  772.     }
  773.  
  774.     /* decode modified characters */
  775.     for (offs = 0;offs < 256;offs++)
  776.     {
  777.         if (dirtycharacter1[offs] == 1)
  778.         {
  779.             decodechar(Machine->gfx[0],offs,taitosj_characterram,Machine->drv->gfxdecodeinfo[0].gfxlayout);
  780.             dirtycharacter1[offs] = 0;
  781.         }
  782.         if (dirtycharacter2[offs] == 1)
  783.         {
  784.             decodechar(Machine->gfx[2],offs,taitosj_characterram + 0x1800,Machine->drv->gfxdecodeinfo[2].gfxlayout);
  785.             dirtycharacter2[offs] = 0;
  786.         }
  787.     }
  788.     /* decode modified sprites */
  789.     for (offs = 0;offs < 64;offs++)
  790.     {
  791.         if (dirtysprite1[offs] == 1)
  792.         {
  793.             decodechar(Machine->gfx[1],offs,taitosj_characterram,Machine->drv->gfxdecodeinfo[1].gfxlayout);
  794.             dirtysprite1[offs] = 0;
  795.         }
  796.         if (dirtysprite2[offs] == 1)
  797.         {
  798.             decodechar(Machine->gfx[3],offs,taitosj_characterram + 0x1800,Machine->drv->gfxdecodeinfo[3].gfxlayout);
  799.             dirtysprite2[offs] = 0;
  800.         }
  801.     }
  802.  
  803.  
  804.     /* for every character in the Video RAM, check if it has been modified */
  805.     /* since last time and update it accordingly. */
  806.     for (offs = videoram_size - 1;offs >= 0;offs--)
  807.     {
  808.         if (dirtybuffer[offs])
  809.         {
  810.             int sx,sy;
  811.  
  812.  
  813.             dirtybuffer[offs] = 0;
  814.  
  815.             sx = offs % 32;
  816.             sy = offs / 32;
  817.             if (flipscreen[0]) sx = 31 - sx;
  818.             if (flipscreen[1]) sy = 31 - sy;
  819.  
  820.             drawgfx(taitosj_tmpbitmap[0],Machine->gfx[taitosj_colorbank[0] & 0x08 ? 2 : 0],
  821.                     videoram[offs],
  822.                     (taitosj_colorbank[0] & 0x07) + 8,    /* use transparent pen 0 */
  823.                     flipscreen[0],flipscreen[1],
  824.                     8*sx,8*sy,
  825.                     0,TRANSPARENCY_NONE,0);
  826.         }
  827.  
  828.         if (dirtybuffer2[offs])
  829.         {
  830.             int sx,sy;
  831.  
  832.  
  833.             dirtybuffer2[offs] = 0;
  834.  
  835.             sx = offs % 32;
  836.             sy = offs / 32;
  837.             if (flipscreen[0]) sx = 31 - sx;
  838.             if (flipscreen[1]) sy = 31 - sy;
  839.  
  840.             drawgfx(taitosj_tmpbitmap[1],Machine->gfx[taitosj_colorbank[0] & 0x80 ? 2 : 0],
  841.                     taitosj_videoram2[offs],
  842.                     ((taitosj_colorbank[0] >> 4) & 0x07) + 8,    /* use transparent pen 0 */
  843.                     flipscreen[0],flipscreen[1],
  844.                     8*sx,8*sy,
  845.                     0,TRANSPARENCY_NONE,0);
  846.         }
  847.  
  848.         if (dirtybuffer3[offs])
  849.         {
  850.             int sx,sy;
  851.  
  852.  
  853.             dirtybuffer3[offs] = 0;
  854.  
  855.             sx = offs % 32;
  856.             sy = offs / 32;
  857.             if (flipscreen[0]) sx = 31 - sx;
  858.             if (flipscreen[1]) sy = 31 - sy;
  859.  
  860.             drawgfx(taitosj_tmpbitmap[2],Machine->gfx[taitosj_colorbank[1] & 0x08 ? 2 : 0],
  861.                     taitosj_videoram3[offs],
  862.                     (taitosj_colorbank[1] & 0x07) + 8,    /* use transparent pen 0 */
  863.                     flipscreen[0],flipscreen[1],
  864.                     8*sx,8*sy,
  865.                     0,TRANSPARENCY_NONE,0);
  866.         }
  867.     }
  868.  
  869.  
  870.     /*called here because drawplayfield() uses its output (spritearea[32]) */
  871.     calculate_sprites_areas();
  872.  
  873.     /* first of all, fill the screen with the background color */
  874.     fillbitmap(bitmap,Machine->gfx[0]->colortable[8 * (taitosj_colorbank[1] & 0x07)],
  875.             &Machine->drv->visible_area);
  876.  
  877.     for (i = 0;i < 4;i++)
  878.         drawplane(draworder[*taitosj_video_priority & 0x1f][i],bitmap);
  879.  
  880.  
  881.     check_sprite_sprite_collision();
  882.  
  883.     /*check_sprite_plane_collision() uses drawn bitmaps, so it must me called _AFTER_ drawplane() */
  884.     check_sprite_plane_collision();
  885.  
  886.     /*check_plane_plane_collision();*/    /*not implemented !!!*/
  887. }
  888.